维基词条:Shebang

简介

在计算领域中,Shebang(也称为Hashbang)是一个由井号和叹号构成的字符序列#!,其出现在文本文件的第一行的前两个字符。

在文件中存在Shebang的情况下,类Unix操作系统的程序加载器会分析Shebang后的内容,将这些内容作为解释器指令,并调用该指令,并将载有Shebang的文件路径作为该解释器的参数。

例如,以指令#!/bin/sh开头的文件在执行时会实际调用/bin/sh程序(通常是Bourne shell或兼容的shell,例如bash、dash等)来执行。这行内容也是shell脚本的标准起始行。

由于#符号在许多脚本语言中都是注释标识符,Shebang的内容会被这些脚本解释器自动忽略。 在#字符不是注释标识符的语言中,例如Scheme,解释器也可能忽略以#!开头的首行内容,以提供与Shebang的兼容性。

"Shebang"或者说"Hashbang"的名字有时也被当做Ajax应用程序中的分段标识符,用于浏览器的状态保存;Google网站站长中心提到,以叹号开头的分段标识符(即...url#!state...)会为Google的网页爬虫所索引。

语法

Shebang这一语法特性由#!开头,即井号和叹号。 在开头字符之后,可以有一个或数个空白字符,后接解释器的绝对路径,用于调用解释器。

在直接调用脚本时,调用者会利用Shebang提供的信息调用相应的解释器,从而使得脚本文件的调用方式与普通的可执行文件类似。

例子

下面列出了一些典型的 shebang 解释器指令:

  • #!/bin/sh—使用sh,即Bourne shell或其它兼容shell执行脚本
  • #!/bin/csh—使用csh,即C shell执行
  • #!/usr/bin/perl -w—使用带警告的Perl执行
  • #!/usr/bin/python -O—使用具有代码优化的Python执行
  • #!/usr/bin/php—使用PHP的命令行解释器执行

在许多系统上,/bin/sh软链接或硬链接到Bash,而/bin/csh则链接到tcsh,因此设定前面的解释器实际上是运行的与之兼容的,或改进的版本。

Shebang行也可以包含需要传递到解释器的特定选项(见下文的Perl例子)。然而,选项传递的方式随实现的不同而不同。

用途

解释器指令允许脚本和数据文件充当系统命令,无需在调用时由用户指定解释器,从而对用户和其它程序隐藏其实现细节。

假设/usr/local/bin/foo中有一以下行开头的Bourne shell脚本 #!/bin/sh -x 而它被如此调用("$"是命令提示符) $ foo bar 该命令的输出等同于 $ /bin/sh -x /usr/local/bin/foo bar 除了argv[0]被设定为脚本的文件名,而非解释器的文件名外。

由于sh从其命令行指定的文件中读取命令,上面的命令就会执行/usr/local/bin/foo中的命令,同时,将bar作为foo命令的参数$1

由于shebang开头的井号也是Bourne shell和许多其它解释性语言的注释符,因此在这些语言中,解释器指令本身会被解释器认为是单纯的注释而跳过。 然而,并不是每一种解释器都会自动忽略shebang行,例如对于下面的脚本,cat会把文件中的两行都输出到标准输出中。

#!/bin/cat
Hello world!

使用#!/usr/bin/env 脚本解释器名称是一种常见的在不同平台上都能正确找到解释器的办法。

Linux的操作系统的文件一般是UTF-8编码。如果脚本文件是以UTF-8的BOM(0xEF 0xBB 0xBF)开头的,那么exec函数将不会启动shebang指定的解释器来执行该脚本。因此,Linux的脚本文件不应在文件开头包含UTF-8的BOM。

#!/bin/bash

#!/bin/bash是指此脚本使用/bin/bash来解释执行。

在脚本中,只有第一行的#!/bin/bash才起声明解释器作用,其余位置均为注释

脚本第一行的解释器路径一定要正确,不正确会报错(未验证)

常用的解释器注释

  • #!/bin/bash
  • #!/bin/sh
  • 不写:脚本会默认当前用户登录的shell,为脚本解释器
  • 其他

脚本里声明解释器类型和运行时指定解释器效果相同

#!/bin/sh一般设成#!/bin/bash的软链接,在一般的linux系统当中(如redhat),使用sh调用执行脚本相当于打开了bash的POSIX标准模式,也就是说 /bin/sh 相当于 /bin/bash --posix

#!/bin/bash#!/bin/bash --posix的区别

  • 不开启posix时,运行出错会报错,但继续执行后续
  • 开启posix时,运行出错会报错,不继续执行后续